package minmax;

import java.util.Iterator;

/**
 * describes a state of a particular game and allows apply and
 * withdraw moves. Each state could be estimated by heuristic
 * function.
 *
 * @param <M> is type that describes moves, valid for this game
 * 
 * @author alex
 */
public interface GameState<M extends GameMove> extends Cloneable {

	/**
	 * changes the state
	 * 
	 * @param step is a valid game move
	 */
	void move(M step);
	
	/**
	 * discards the last move (there must exist)
	 */
	void backtrack();
	
	/**
	 * gives possible moves from this state.
	 * The game must be in state other then finished
	 * 
	 * @return iterator over non-empty set
	 */
	Iterator<M> moves();
	
	/**
	 * checks whether a given move can be performed
	 * in the current state
	 * 
	 * @param move is a move instance
	 * @return validation result
	 */
	boolean canMove(M move);
	
	/**
	 * give a player that is about to take a move
	 * 
	 * @return current player
	 */
	boolean player();
	
	/**
	 * heuristic estimate of a current game state, considering
	 * current player as either opponent (</code>false</code>)
	 * or the player we are playing for (</code>true</code>)
	 * 
	 * @param maximize determines between two players
	 * @return a value other then +/- infinity
	 */
	int evaluate(boolean maximize);
	
	/**
	 * @return whether this game is finished and no further moves possible
	 */
	boolean isFinished();
	
	/**
	 * when a game is finished, it's outcome can be questioned
	 * 
	 * @return the outcome
	 */
	GameOutcome outcome();
	
	/**
	 * @return a deep copy of current game state
	 */
	GameState<M> clone();
	
	/**
	 * state can be compared for equality
	 * 
	 * @return whether an object is equal to this state
	 */
	boolean equals(Object o);
	
	/**
	 * @return hash code
	 */
	int hashCode();

}
